home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright (c) 1992, Brian Berliner and Jeff Polk
- * Copyright (c) 1989-1992, Brian Berliner
- *
- * You may distribute under the terms of the GNU General Public License as
- * specified in the README file that comes with the CVS 1.3 kit.
- *
- * Entries file to Files file
- *
- * Creates the file Files containing the names that comprise the project, from
- * the Entries file.
- */
-
- #include "cvs.h"
-
- #ifndef lint
- static char rcsid[] = "@(#)entries.c 1.37 92/03/31";
- #endif
-
- #if __STDC__
- static Node *AddEntryNode (List * list, char *name, char *version,
- char *timestamp, char *options, char *tag,
- char *date);
- #else
- static Node *AddEntryNode ();
- #endif /* __STDC__ */
-
- static FILE *entfile;
- static char *entfilename; /* for error messages */
-
- /*
- * Write out the line associated with a node of an entries file
- */
- static int
- write_ent_proc (node)
- Node *node;
- {
- Entnode *p;
-
- p = (Entnode *) node->data;
- if (fprintf (entfile, "/%s/%s/%s/%s/", node->key, p->version,
- p->timestamp, p->options) == EOF)
- error (1, errno, "cannot write %s", entfilename);
- if (p->tag)
- {
- if (fprintf (entfile, "T%s\n", p->tag) == EOF)
- error (1, errno, "cannot write %s", entfilename);
- }
- else if (p->date)
- {
- if (fprintf (entfile, "D%s\n", p->date) == EOF)
- error (1, errno, "cannot write %s", entfilename);
- }
- else if (fprintf (entfile, "\n") == EOF)
- error (1, errno, "cannot write %s", entfilename);
- return (0);
- }
-
- /*
- * write out the current entries file given a list, making a backup copy
- * first of course
- */
- static void
- write_entries (list)
- List *list;
- {
- /* open the new one and walk the list writing entries */
- entfilename = CVSADM_ENTBAK;
- entfile = open_file (entfilename, "w+");
- (void) walklist (list, write_ent_proc);
- if (fclose (entfile) == EOF)
- error (1, errno, "error closing %s", entfilename);
-
- /* now, atomically (on systems that support it) rename it */
- rename_file (entfilename, CVSADM_ENT);
- }
-
- /*
- * Removes the argument file from the Entries file if necessary.
- */
- void
- Scratch_Entry (list, fname)
- List *list;
- char *fname;
- {
- Node *node;
-
- if (trace)
- (void) fprintf (stderr, "-> Scratch_Entry(%s)\n", fname);
-
- /* hashlookup to see if it is there */
- if ((node = findnode (list, fname)) != NULL)
- {
- delnode (node); /* delete the node */
- if (!noexec)
- write_entries (list); /* re-write the file */
- }
- }
-
- /*
- * Enters the given file name/version/time-stamp into the Entries file,
- * removing the old entry first, if necessary.
- */
- void
- Register (list, fname, vn, ts, options, tag, date)
- List *list;
- char *fname;
- char *vn;
- char *ts;
- char *options;
- char *tag;
- char *date;
- {
- Node *node;
-
- if (trace)
- (void) fprintf (stderr, "-> Register(%s, %s, %s, %s, %s %s)\n",
- fname, vn, ts, options, tag ? tag : "",
- date ? date : "");
- /* was it already there? */
- if ((node = findnode (list, fname)) != NULL)
- {
- /* take it out */
- delnode (node);
-
- /* add the new one and re-write the file */
- (void) AddEntryNode (list, fname, vn, ts, options, tag, date);
- if (!noexec)
- write_entries (list);
- }
- else
- {
- /* add the new one */
- node = AddEntryNode (list, fname, vn, ts, options, tag, date);
-
- if (!noexec)
- {
- /* append it to the end */
- entfilename = CVSADM_ENT;
- entfile = open_file (entfilename, "a");
- (void) write_ent_proc (node);
- if (fclose (entfile) == EOF)
- error (1, errno, "error closing %s", entfilename);
- }
- }
- }
-
- /*
- * Node delete procedure for list-private sticky dir tag/date info
- */
- static void
- freesdt (p)
- Node *p;
- {
- struct stickydirtag *sdtp;
-
- sdtp = (struct stickydirtag *) p->data;
- if (sdtp->tag)
- free (sdtp->tag);
- if (sdtp->date)
- free (sdtp->date);
- if (sdtp->options)
- free (sdtp->options);
- free ((char *) sdtp);
- }
-
- /*
- * Read the entries file into a list, hashing on the file name.
- */
- List *
- ParseEntries (aflag)
- int aflag;
- {
- List *entries;
- char line[MAXLINELEN];
- char *cp, *user, *vn, *ts, *options;
- char *tag_or_date, *tag, *date;
- char *dirtag, *dirdate;
- int lineno = 0;
- FILE *fpin;
-
- /* get a fresh list... */
- entries = getlist ();
-
- /*
- * Parse the CVS/Tag file, to get any default tag/date settings. Use
- * list-private storage to tuck them away for Version_TS().
- */
- ParseTag (&dirtag, &dirdate);
- if (aflag || dirtag || dirdate)
- {
- struct stickydirtag *sdtp;
-
- sdtp = (struct stickydirtag *) xmalloc (sizeof (*sdtp));
- bzero ((char *) sdtp, sizeof (*sdtp));
- sdtp->aflag = aflag;
- sdtp->tag = xstrdup (dirtag);
- sdtp->date = xstrdup (dirdate);
-
- /* feed it into the list-private area */
- entries->list->data = (char *) sdtp;
- entries->list->delproc = freesdt;
- }
-
- again:
- fpin = fopen (CVSADM_ENT, "r");
- if (fpin == NULL)
- error (0, errno, "cannot open %s for reading", CVSADM_ENT);
- else
- {
- while (fgets (line, sizeof (line), fpin) != NULL)
- {
- lineno++;
- if (line[0] == '/')
- {
- user = line + 1;
- if ((cp = index (user, '/')) == NULL)
- continue;
- *cp++ = '\0';
- vn = cp;
- if ((cp = index (vn, '/')) == NULL)
- continue;
- *cp++ = '\0';
- ts = cp;
- if ((cp = index (ts, '/')) == NULL)
- continue;
- *cp++ = '\0';
- options = cp;
- if ((cp = index (options, '/')) == NULL)
- continue;
- *cp++ = '\0';
- tag_or_date = cp;
- if ((cp = index (tag_or_date, '\n')) == NULL)
- continue;
- *cp = '\0';
- tag = (char *) NULL;
- date = (char *) NULL;
- if (*tag_or_date == 'T')
- tag = tag_or_date + 1;
- else if (*tag_or_date == 'D')
- date = tag_or_date + 1;
- (void) AddEntryNode (entries, user, vn, ts, options, tag, date);
- }
- else
- {
- /* try conversion only on first line */
- if (lineno == 1)
- {
- (void) fclose (fpin);
- check_entries ((char *) NULL);
- goto again;
- }
- }
- }
- }
-
- /* clean up and return */
- if (fpin)
- (void) fclose (fpin);
- if (dirtag)
- free (dirtag);
- if (dirdate)
- free (dirdate);
- return (entries);
- }
-
- /*
- * Look at the entries file to determine if it is in the old entries format.
- * If so, convert it to the new format.
- */
- void
- check_entries (dir)
- char *dir;
- {
- FILE *fpin, *fpout;
- char tmp[MAXLINELEN];
- char line[MAXLINELEN];
- char entname[MAXLINELEN];
- char entbak[MAXLINELEN];
- char *cp, *user, *rev, *ts, *opt;
-
- if (dir != NULL)
- {
- (void) sprintf (entname, "%s/%s", dir, CVSADM_ENT);
- (void) sprintf (entbak, "%s/%s", dir, CVSADM_ENTBAK);
- }
- else
- {
- (void) strcpy (entname, CVSADM_ENT);
- (void) strcpy (entbak, CVSADM_ENTBAK);
- }
-
- fpin = open_file (entname, "r");
- if (fgets (line, sizeof (line), fpin) == NULL)
- {
- (void) fclose (fpin);
- return;
- }
- (void) fclose (fpin);
- if (line[0] != '/')
- {
- rename_file (entname, entbak);
- fpin = open_file (entbak, "r");
- fpout = open_file (entname, "w+");
- while (fgets (line, sizeof (line), fpin) != NULL)
- {
- if (line[0] == '/')
- {
- if (fputs (line, fpout) == EOF)
- error (1, errno, "cannot write %s", CVSADM_ENT);
- continue;
- }
- rev = line;
- if ((ts = index (line, '|')) == NULL)
- continue;
- *ts++ = '\0';
- if ((user = rindex (ts, ' ')) == NULL)
- continue;
- *user++ = '\0';
- if ((cp = index (user, '|')) == NULL)
- continue;
- *cp = '\0';
- opt = "";
- #ifdef HAVE_RCS5
- #ifdef HAD_RCS4
- opt = "-V4";
- #endif
- #endif
- if (fprintf (fpout, "/%s/%s/%s/%s/\n", user, rev, ts, opt) == EOF)
- error (1, errno, "cannot write %s", CVSADM_ENT);
- }
- (void) fclose (fpin);
- if (fclose (fpout) == EOF)
- error (1, errno, "cannot close %s", entname);
-
- /* clean up any old Files or Mod files */
- if (dir != NULL)
- (void) sprintf (tmp, "%s/%s", dir, CVSADM_FILE);
- else
- (void) strcpy (tmp, CVSADM_FILE);
- if (isfile (tmp))
- (void) unlink (tmp);
-
- if (dir != NULL)
- (void) sprintf (tmp, "%s/%s", dir, CVSADM_MOD);
- else
- (void) strcpy (tmp, CVSADM_MOD);
- if (isfile (tmp))
- (void) unlink (tmp);
- }
- }
-
- /*
- * Free up the memory associated with the data section of an ENTRIES type
- * node
- */
- static void
- Entries_delproc (node)
- Node *node;
- {
- Entnode *p;
-
- p = (Entnode *) node->data;
- free (p->version);
- free (p->timestamp);
- free (p->options);
- if (p->tag)
- free (p->tag);
- if (p->date)
- free (p->date);
- free ((char *) p);
- }
-
- /*
- * Get an Entries file list node, initialize it, and add it to the specified
- * list
- */
- static Node *
- AddEntryNode (list, name, version, timestamp, options, tag, date)
- List *list;
- char *name;
- char *version;
- char *timestamp;
- char *options;
- char *tag;
- char *date;
- {
- Node *p;
- Entnode *entdata;
-
- /* get a node and fill in the regular stuff */
- p = getnode ();
- p->type = ENTRIES;
- p->delproc = Entries_delproc;
-
- /* this one gets a key of the name for hashing */
- p->key = xstrdup (name);
-
- /* malloc the data parts and fill them in */
- p->data = xmalloc (sizeof (Entnode));
- entdata = (Entnode *) p->data;
- entdata->version = xstrdup (version);
- entdata->timestamp = xstrdup (timestamp);
- entdata->options = xstrdup (options);
- if (entdata->options == NULL)
- entdata->options = xstrdup ("");/* must be non-NULL */
- entdata->tag = xstrdup (tag);
- entdata->date = xstrdup (date);
-
- /* put the node into the list */
- if (addnode (list, p) != 0)
- error (0, 0, "Duplicate filename in entries file (%s) -- ignored",
- name);
-
- return (p);
- }
-
- /*
- * Write out/Clear the CVS/Tag file.
- */
- void
- WriteTag (dir, tag, date)
- char *dir;
- char *tag;
- char *date;
- {
- FILE *fout;
- char tmp[PATH_MAX];
-
- if (noexec)
- return;
-
- if (dir == NULL)
- (void) strcpy (tmp, CVSADM_TAG);
- else
- (void) sprintf (tmp, "%s/%s", dir, CVSADM_TAG);
-
- if (tag || date)
- {
- fout = open_file (tmp, "w+");
- if (tag)
- {
- if (fprintf (fout, "T%s\n", tag) == EOF)
- error (1, errno, "write to %s failed", tmp);
- }
- else
- {
- if (fprintf (fout, "D%s\n", date) == EOF)
- error (1, errno, "write to %s failed", tmp);
- }
- if (fclose (fout) == EOF)
- error (1, errno, "cannot close %s", tmp);
- }
- else
- (void) unlink_file (tmp);
- }
-
- /*
- * Parse the CVS/Tag file for the current directory.
- */
- void
- ParseTag (tagp, datep)
- char **tagp;
- char **datep;
- {
- FILE *fp;
- char line[MAXLINELEN];
- char *cp;
-
- if (tagp)
- *tagp = (char *) NULL;
- if (datep)
- *datep = (char *) NULL;
- fp = fopen (CVSADM_TAG, "r");
- if (fp)
- {
- if (fgets (line, sizeof (line), fp) != NULL)
- {
- if ((cp = rindex (line, '\n')) != NULL)
- *cp = '\0';
- if (*line == 'T' && tagp)
- *tagp = xstrdup (line + 1);
- else if (*line == 'D' && datep)
- *datep = xstrdup (line + 1);
- }
- (void) fclose (fp);
- }
- }
-